home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 4
/
FM Towns Free Software Collection 4 - Disc 1.iso
/
data
/
maglrex
/
magl.c
next >
Wrap
C/C++ Source or Header
|
1991-10-18
|
12KB
|
499 lines
/*
* 'Magl.rex' for FM-TOWNS
*
* - MAKIchan Graphic loader is not 鮪だ! -
*
* Version 1.03 Update 1991/05/12
*
* programmed by MALOR
*/
/*
* 1991/04/25 v1.00 正常に展開されたぞ
* 05/06 v1.01 カラーパレットの障害を修正
* 10 v1.02 スタックにヒープを取るようにして、
* 実行ファイル512Kの地獄を脱した(^_^;)
* 12 v1.03 256色モードのパレットの障害を修正
* 今後の課題
*/
#include <egb.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "pixel.h"
#define VERSION "1.03"
#define UPDATE "1991/05/12 11:28"
#define tolower(x) ((x)<'Z')&&((x)>'A')?((x)-'A'+'a'):(x)
#define FNAME16 0x0006118c
#define FNAME25 0x000610fc
#define FNAME32 0x000614dc
#define PALADDR16 0x00062B58 /* 16色モード時 */
#define RGB2HSV16 0x0002C774
#define PALADDR25 0x00062A08 /* 256色モード時 */
#define RGB2HSV25 0x0002c274
#define MemorySize 512*1024 /* Buffer is 512Kbyte */
#ifndef NULL
#define NULL 0
#endif
#define FALSE 0
#define TRUE -1
#define EOC 0x1a /* End Of Comment */
#define CR 0x0d
#define LF 0x0a
#define BufSize 256
#define PLANE20 0x001c
#define PLANE21 0x0104
#define PLANE10 0x010c
#define PALNO 0xfd90
#define PALB 0xfd92
#define PALR 0xfd94
#define PALG 0xfd96
#define LINE200 0x01 /* 200ラインフラグ */
#define COL8 0x02 /* 8色フラグ */
#define DIGITAL 0x04 /* デジタルフラグ */
#define COL256 0x80 /* 256色フラグ */
#define VRAM 0x20 /* 強制VRAM展開フラグ */
typedef union {
struct { unsigned char h,l; } m;
unsigned short s;
} WORD;
typedef struct {
char header; /* ヘッダの先頭 */
char machine; /* 機種コード */
char rflg; /* 機種依存フラグ */
char screen; /* スクリーンモード */
short lx; /* 表示開始位置X */
short ly; /* 表示開始位置Y */
short rx; /* 表示終了位置X */
short ry; /* 表示終了位置Y */
int offa; /* フラグAのオフセット */
int offb; /* フラグBのオフセット */
int sizb; /* フラグBのサイズ */
int offp; /* ピクセルのオフセット */
int sizp; /* ピクセルのサイズ */
} MAGHEADER;
typedef struct {
char id[8]; /* MAKI識別子'MAKI01A ' or 'MAKI01B ' */
char comment[24]; /* セーバー作者コメント */
WORD sizb; /* フラグBのサイズ */
WORD sizpa; /* ピクセルAのサイズ */
WORD sizpb; /* ピクセルBのサイズ */
WORD tile; /* タイルデータのサイズ */
WORD lx; /* 表示開始位置X */
WORD ly; /* 表示開始位置Y */
WORD rx; /* 表示終了位置X */
WORD ry; /* 表示終了位置Y */
} MKIHEADER;
typedef struct {
unsigned short g,r,b,h,s,v;
} PALTABLE;
typedef void (*PALCONV)( int r, int g, int b, short *h, short *s, short *v );
/* Prototype declaration */
extern void load(int dummy,int mode,char *egbwork,char *usrwork,int sx,int sy,int ex,int ey);
void load(int dummy,int mode,char *egbwork,char *usrwork,int sx,int sy,int ex,int ey);
char *getext(char *arg);
int memory_allocate(int size);
int stringcmp(char *s,char *d);
int mag_get_head(FILE *fp);
int mag_decode(FILE *fp,int mode,int x,int y);
int mki_get_head(FILE *fp);
int mki_decode(FILE *fp,int mode,int x,int y);
int set_palette(void);
/* Global Vari. */
extern char mem[]; /* Heap Buffer pointer */
char *egb; /* EGBworkへのポインタ(Global版) */
MAGHEADER maghead; /* MAGのヘッダ */
MKIHEADER mkihead; /* MAKIのベッダ */
int sizp; /* MAKIのピクセルサイズ */
int siza; /* MAGのflag aのサイズ */
int headtop; /* MAGのヘッダのオフセット */
char pal[768]; /* 現在のパレット情報 */
char *flga,*flgb,*flg,*pix; /* flag&pixel格納アドレス */
int xpixel; /* 横方向のピクセル数の半分 */
/* 現在メモリに存在するイメージ情報 */
char *vram=NULL; /* イメージ格納アドレス */
int screen_mode; /* スクリーンモード(MAG互換) */
/* Main program */
void load(int dummy,int mode,char *egbwork,char *usrwork,int sx,int sy,int ex,int ey)
{
char *s,*d,*p,fname[BufSize];
FILE *fp;
int dx,dy,i;
dx=0; dy=0;
egb = egbwork;
if (mode == 4)
p = (char *)FNAME16;
else if (mode == 8)
p = (char *)FNAME25;
else if (mode == 16)
p = (char *)FNAME32;
else
return;
for(d=fname,s=p,i=0;i<8;i++)
*d++ = ((*s!='\0')&&(*s!='.'))?(*s++):' ';
for(s=".mag";*s!='\0';*d++ = *s++);
*d = '\0';
if ((fp=fopen(fname,"rb"))==NULL) {
for(d=getext(fname),s="mki";*s!='\0';*d++ = *s++);
*d = '\0';
if ((fp=fopen(fname,"rb"))==NULL)
return;
}
if (mag_get_head(fp)) {
if ((maghead.screen&COL256)&&(mode!=8))
return;
if ((!(maghead.screen&COL256))&&(mode!=4))
return;
set_palette();
/* printf("magl : start mag_decode \n"); */
mag_decode(fp,mode,dx,dy);
} else if (mki_get_head(fp)) {
if (mode!=4)
return;
set_palette();
mki_decode(fp,mode,dx,dy);
}
fclose(fp);
}
char *getext(char *arg)
{
char *p;
for(p=arg;*arg!='\0';arg++)
if (*arg=='\\') p=arg+1;
for(;*p!='.'&&*p!='\0';p++);
if (*p=='\0')
return NULL;
else
return p+1;
}
int memory_allocate(int size)
{
static char *bottom = mem;
static int total_size = 0;
if (total_size+size>=MemorySize)
return 0;
else {
bottom += size;
total_size += size;
return (int)bottom-size;
}
}
int stringcmp(char *s,char *d)
{
for (;*s!='\0';s++,d++)
if ((tolower(*s))!=(tolower(*d)))
return FALSE;
return TRUE;
}
int mag_get_head(FILE *fp)
{
char buf[10];
fseek(fp,0,0);
fread(buf,1,8,fp);
if (!stringcmp("MAKI02",buf))
return FALSE;
fseek(fp,0,0);
for(headtop=0;;headtop++) {
if (fread(buf,1,1,fp)!=1)
return FALSE;
if (*buf==EOC) {
headtop++;
break;
}
}
if (fread((char *)&maghead,1,sizeof(MAGHEADER),fp)<sizeof(MAGHEADER))
return FALSE;
xpixel = (maghead.screen&COL256)?(maghead.rx/4-maghead.lx/4+1)
:(maghead.rx/8-maghead.lx/8+1);
siza = (xpixel*(maghead.ry-maghead.ly+1)+7) / 8;
screen_mode = maghead.screen;
fread(pal,1,(screen_mode&COL256)?768:48,fp); /* palette read */
return TRUE;
}
int mag_decode(FILE *fp,int mode,int x,int y)
{
/* flag a size */
xpixel = (maghead.screen&COL256)?(maghead.rx/4-maghead.lx/4+1)
:(maghead.rx/8-maghead.lx/8+1);
siza = (xpixel*(maghead.ry-maghead.ly+1)+7) / 8;
/* xpixel = 横方向のピクセル数の半分 */
if ((flga=(char *)memory_allocate(siza))==NULL) {
printf("magl : can't allocate memory ( flag a )\n");
goto Exit;
}
if ((flgb=(char *)memory_allocate(maghead.sizb))==NULL) {
printf("magl : can't allocate memory ( flag b )\n");
goto Exit;
}
if ((pix=(char *)memory_allocate(maghead.sizp))==NULL) {
printf("magl : can't allocate memory ( pixcel )\n");
goto Exit;
}
if ((flg=(char *)memory_allocate(siza*8))==NULL) {
printf("magl : can't allocate memory ( flag )\n");
goto Exit;
}
fseek(fp,headtop+maghead.offa,0); /* flag a read */
if (fread(flga,1,siza,fp)!=siza)
printf("magl : inproper size ( flag a )\n");
fseek(fp,headtop+maghead.offb,0); /* flag b read */
if (fread(flgb,1,maghead.sizb,fp)!=maghead.sizb)
printf("magl : inproper size ( flag b )\n");
fseek(fp,headtop+maghead.offp,0); /* pixcel read */
if (fread(pix,1,maghead.sizp,fp)!=maghead.sizp)
printf("magl : inproper size ( pixcel )\n");
Lineofs = (unsigned int)1024*((maghead.screen&COL256)?2:1);
Mofs[0] = -(int)(( 0+ 0*Lineofs)/2);
Mofs[1] = -(int)(( 4+ 0*Lineofs)/2);
Mofs[2] = -(int)(( 8+ 0*Lineofs)/2);
Mofs[3] = -(int)((16+ 0*Lineofs)/2);
Mofs[4] = -(int)(( 0+ 1*Lineofs)/2);
Mofs[5] = -(int)(( 4+ 1*Lineofs)/2);
Mofs[6] = -(int)(( 0+ 2*Lineofs)/2);
Mofs[7] = -(int)(( 4+ 2*Lineofs)/2);
Mofs[8] = -(int)(( 8+ 2*Lineofs)/2);
Mofs[9] = -(int)(( 0+ 4*Lineofs)/2);
Mofs[10] = -(int)(( 4+ 4*Lineofs)/2);
Mofs[11] = -(int)(( 8+ 4*Lineofs)/2);
Mofs[12] = -(int)(( 0+ 8*Lineofs)/2);
Mofs[13] = -(int)(( 4+ 8*Lineofs)/2);
Mofs[14] = -(int)(( 8+ 8*Lineofs)/2);
Mofs[15] = -(int)(( 0+16*Lineofs)/2);
Lineofs /= 2;
if ((maghead.rx-maghead.lx)>1023) {
printf("magl : picture is too wide \n");
goto Exit;
}
if ((maghead.ry-maghead.ly)>479) {
maghead.ly = 0;
maghead.ry = 479;
y = 0;
}
if ((maghead.rx+x)>1023||(maghead.ry+y)>511
||(maghead.lx+x)<0||(maghead.ly+y)<0) {
x = 0;
y = 0;
}
/* printf("magl : pixcel decode start\n"); */
mag((char *)(&maghead),mode|VRAM
,(x+y*1024)/((maghead.screen&COL256)?1:2),xpixel);
/* printf("magl : pixcel decode end \n"); */
/*
free(flg);
free(pix);
free(flgb);
free(flga);
*/
flg = NULL; pix = NULL; flgb = NULL; flga = NULL;
return TRUE;
Exit:
/*
if (flg!=NULL)
free(flg);
if (pix!=NULL)
free(pix);
if (flgb!=NULL)
free(flgb);
if (flga!=NULL)
free(flga);
*/
flg = NULL; pix = NULL; flgb = NULL; flga = NULL;
return FALSE;
}
int mki_get_head(FILE *fp)
{
unsigned char tmp;
headtop = 0;
fseek(fp,0,0);
if (fread((char *)&mkihead,1,sizeof(MKIHEADER),fp)<sizeof(MKIHEADER))
return FALSE;
if ((!stringcmp("MAKI01A",mkihead.id))&&(!stringcmp("MAKI01B",mkihead.id)))
return FALSE;
/* モトローラ形式 -> インテル形式 */
tmp = mkihead.sizb.m.h ;
mkihead.sizb.m.h = mkihead.sizb.m.l ;
mkihead.sizb.m.l = tmp ;
tmp = mkihead.sizpa.m.h ;
mkihead.sizpa.m.h = mkihead.sizpa.m.l ;
mkihead.sizpa.m.l = tmp ;
tmp = mkihead.sizpb.m.h ;
mkihead.sizpb.m.h = mkihead.sizpb.m.l ;
mkihead.sizpb.m.l = tmp ;
sizp = mkihead.sizpa.s + mkihead.sizpb.s;
screen_mode = 0;
fread(pal,1,48,fp); /* palette read */
}
int mki_decode(FILE *fp,int mode,int x,int y)
{
/* flag a size : 1000 = 320*400 / (4*4) / 8 */
if ((flga=(char *)memory_allocate(1000))==NULL) {
printf("magl : can't allocate memory ( flag a )\n");
return FALSE;
}
if ((flgb=(char *)memory_allocate(mkihead.sizb.s))==NULL) {
printf("magl : can't allocate memory ( flag b )\n");
return FALSE;
}
if ((pix=(char *)memory_allocate(sizp))==NULL) {
printf("magl : can't allocate memory ( pixcel )\n");
return FALSE;
}
/* flag size : 16000 = 320*400 / 8 */
if ((flg=(char *)memory_allocate(16000))==NULL) {
printf("magl : can't allocate memory ( flag )\n");
return FALSE;
}
fread(flga,1,1000,fp); /* flag a read */
fread(flgb,1,mkihead.sizb.s,fp); /* flag b read */
fread(pix,1,sizp,fp); /* pixcel read */
if ((x+639)>1023||(y+399)>511||x<0||y<0) {
x = 0;
y = 0;
}
mki((char *)(&mkihead),mode|VRAM,(x+y*1024)/2);
/* printf("magl : mki pixcel decode end \n"); */
/*
free(flg);
free(pix);
free(flgb);
free(flga);
*/
return TRUE;
}
int set_palette(void)
{
unsigned char *p;
int i,r,g,b;
short h,s,v;
PALCONV *rgb_hsv1,*rgb_hsv2;
PALTABLE *rgb_val;
if (screen_mode&COL256) {
rgb_hsv1 = (PALCONV *)RGB2HSV25;
rgb_hsv2 = (PALCONV *)(&rgb_hsv1);
rgb_val = (PALTABLE *)PALADDR25;
for (i=0,p=(unsigned char *)pal;i<256;i++) {
g = (int)*p++;
r = (int)*p++;
b = (int)*p++;
outpb(PALNO,i);
outpb(PALB,b);
outpb(PALR,r);
outpb(PALG,g);
(*rgb_hsv2)(r,g,b,&h,&s,&v);
rgb_val->r = (unsigned short)r;
rgb_val->g = (unsigned short)g;
rgb_val->b = (unsigned short)b;
rgb_val->h = (unsigned short)h;
rgb_val->s = (unsigned short)s;
rgb_val->v = (unsigned short)v;
rgb_val += 1;
}
} else {
rgb_hsv1 = (PALCONV *)RGB2HSV16;
rgb_hsv2 = (PALCONV *)(&rgb_hsv1);
rgb_val = (PALTABLE *)PALADDR16;
for (i=0,p=(unsigned char *)pal;i<16;i++) {
g = ((int)*p++)&0xf0;
r = ((int)*p++)&0xf0;
b = ((int)*p++)&0xf0;
outpb(PALNO,i);
outpb(PALB,b);
outpb(PALR,r);
outpb(PALG,g);
if (r) r |= 0xf;
if (g) g |= 0xf;
if (b) b |= 0xf;
(*rgb_hsv2)(r,g,b,&h,&s,&v);
rgb_val->r = (unsigned short)r;
rgb_val->g = (unsigned short)g;
rgb_val->b = (unsigned short)b;
rgb_val->h = (unsigned short)h;
rgb_val->s = (unsigned short)s;
rgb_val->v = (unsigned short)v;
rgb_val += 1;
}
}
return TRUE ;
}